/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Surface.h"
#include "面.h"


//#include <向量.h>
#include <file_载入保存数据.h>
#include <字符串转换.h>

#include <omp.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype.h>



#include "intern/矢量绘图着色材质.h"
#include "intern/平面几何数据生成.h"

#include "底层绘图/底层绘图框架.h"
#include "底层绘图/intern/Vulkan/Vulkan框架.h"
#include "底层绘图/intern/Vulkan/线管绘制.h"
#include "底层绘图/intern/Vulkan/buffer/Vk图像.h"
#include "底层绘图/intern/Vulkan/线管/着色器.h"
#include "底层绘图/intern/Vulkan/线管/线管.h"

#include "core/引擎配置.h"
#include "core/动画/an_曲线.h"

#include "材质/S_Material.h"
#include "纹理/纹理.h"


static FT_Library glibrary = 0;


//S_板载缓存* S_2D画布::m_间接绘制图元顶点 = nullptr;
//S_板载缓存* S_2D画布::g变换GPU缓存       = nullptr;
//S_板载缓存* S_2D画布::g行文本变换GPU缓存 = nullptr;
//S_板载缓存* S_2D画布::g行文本颜色GPU缓存 = nullptr;

S_板载缓存* S_2D画布::g字符GPU缓存       = nullptr;
S_板载缓存* S_2D画布::g表格变换GPU缓存   = nullptr;
S_板载缓存* S_2D画布::g表格颜色GPU缓存   = nullptr;

S_板载缓存* S_2D画布::g凸包变换          = nullptr;
S_板载缓存* S_2D画布::g凸包颜色          = nullptr;
S_板载缓存* S_2D画布::g凸包线属性        = nullptr;

S_板载缓存* S_2D画布::g凸包纹理属性      = nullptr;
S_板载缓存* S_2D画布::g凸包渐变属性      = nullptr;
S_板载缓存* S_2D画布::g凸包渐变控制属性  = nullptr;
S_板载缓存* S_2D画布::g凸包色轮属性      = nullptr;

S_板载缓存* S_2D画布::g图标变换          = nullptr;
S_板载缓存* S_2D画布::g图标颜色          = nullptr;

S_板载缓存* S_2D画布::g纹理变换          = nullptr;


S_板载缓存* S_2D画布::g线段 = nullptr;


S_GPU内存块 S_2D画布::g预设_矩形 = {};
S_GPU内存块 S_2D画布::g预设_圆形 = {};
S_GPU内存块 S_2D画布::g预设_圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_左圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_右圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_上圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_下圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_左上圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_右上圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_左下圆角矩形 = {};
S_GPU内存块	S_2D画布::g预设_右下圆角矩形 = {};


S_Widget预设凸包图元			S_UI渲染环境::m_图元ID;
std::vector< S_2D图元顶点>	S_UI渲染环境::m_预设图元顶点;



#ifdef _DEBUG 

#pragma comment(lib, "D:/U/Project/packages/freetype2.2.6.0.1/build/native/lib/x64/Debug/freetype26d.lib")

#else

#pragma comment(lib, "D:/U/Project/packages/freetype2.2.6.0.1/build/native/lib/x64/Release/freetype26.lib")

#endif




uvec2	S_Widget预设凸包图元::m_矩形;
uvec2	S_Widget预设凸包图元::m_左圆角矩形;
uvec2	S_Widget预设凸包图元::m_右圆角矩形;
uvec2	S_Widget预设凸包图元::m_上圆角矩形;
uvec2	S_Widget预设凸包图元::m_下圆角矩形;
uvec2	S_Widget预设凸包图元::m_圆角矩形;
uvec2	S_Widget预设凸包图元::m_左上圆角矩形;
uvec2	S_Widget预设凸包图元::m_右上圆角矩形;
uvec2	S_Widget预设凸包图元::m_圆形;
uvec2	S_Widget预设凸包图元::m_竖向圆角连接线;
uvec2	S_Widget预设凸包图元::m_横向圆角连接线;
uvec2	S_Widget预设凸包图元::m_竖向斜角连接线;
uvec2	S_Widget预设凸包图元::m_横线;
uvec2	S_Widget预设凸包图元::m_竖线;
uvec2	S_Widget预设凸包图元::m_斜线;
uvec2	S_Widget预设凸包图元::m_生成C形左拐角连接线;
uvec2	S_Widget预设凸包图元::m_生成C形右拐角连接线;
uvec2	S_Widget预设凸包图元::m_生成L形下拐角连接线;
uvec2	S_Widget预设凸包图元::m_生成L形上拐角连接线;




Inline S_Surface3D* f_surface_Create(S_设备环境& Ctx3D) {
	S_Surface3D* face = (S_Surface3D*)malloc(sizeof(S_Surface3D));
	face->m_交换ID = uint8(0);
	face->m_Ctx = &Ctx3D;

	for (uint32 i = 0; i < 6; ++i) {
		face->m_Color[i] = nullptr;
		face->m_Depth[i] = nullptr;
	}

	face->m_纹理数量 = 0;
	face->m_交换ID = 0;
	return face;
}



S_Surface3D* f_surface_Create(S_设备环境& Ctx3D, const uvec2& size, bool 多重采样, bool 创建单层输出, bool 阴影) {
	S_Surface3D* face = f_surface_Create(Ctx3D);
	auto df = f_vk_get绘图环境(Ctx3D);
	
	uint32 纹理数量;
	

	if (阴影) {
		face->m_帧缓存 = f_fb_创建阴影帧缓存(Ctx3D, size, face->m_Depth[0]);
	}
	else {
		std::vector<uint8> data(size.x * size.y * 4);
		face->m_Color[0] = f_tex_创建帧缓存纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D);
		//uint32 用途 = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		//face->m_Color[0] = S_Vk图像管理::f_创建帧缓存图像(绘图环境.m_设备, 绘图环境.m_内存属性, f_vk_getVK图像格式(E_纹理格式::e_tf_RGBA8U_归一化), E_纹理维度类型::e_2D, { size.x, size.y, 1 }, 绘图环境.m_采样数, 用途);
		face->m_Color[0]->m_Ctx = Ctx3D;

		if (创建单层输出) {
			face->m_纹理数量 = 1;
		}
		else {
			face->m_Color[1] = f_tex_创建帧缓存纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D);
			face->m_Color[2] = f_tex_创建图像纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D);

			f_tex_填充纹理数据(face->m_Color[0], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
			f_tex_填充纹理数据(face->m_Color[1], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
			f_tex_填充纹理数据(face->m_Color[2], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
			face->m_纹理数量 = 2;
		}

		face->m_帧缓存 = f_bd_创建帧缓存(Ctx3D, size, face->m_Color, face->m_纹理数量, 多重采样, 创建单层输出);
	}
	face->m_帧缓存->m_清除颜色 = {0.3,0.3,0.3,1.0};
	return face;
}

S_Surface3D* f_surface3D_创建(S_设备环境& Ctx3D, uvec2 size, E_MS次数 采样次数) {
	auto dc = f_vk_get绘图环境(Ctx3D);

	S_Surface3D* face = f_surface_Create(Ctx3D);
	face->m_纹理数量 = 1;
	f_df_钳制视口大小(*face->m_Ctx, size);
	size /= 16;
	size *= 16;
	size += 16;


	face->m_Color[0] = f_tex_创建帧缓存图像(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, 采样次数);
	face->m_Color[1] = f_tex_创建帧缓存图像(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, 采样次数);
	face->m_Depth[0] = f_tex_创建深度纹理(Ctx3D, {size.x, size.y, 1}, E_MS次数::e_MS_1, E_纹理维度类型::e_2D);

	f_tex_安装纹理采样器(face->m_Color[0], f_g_纹理().g_颜色纹理采样器);
	f_tex_安装纹理采样器(face->m_Color[1], f_g_纹理().g_颜色纹理采样器);
	f_tex_安装纹理采样器(face->m_Depth[0], f_g_纹理().g_阴影采样器);

	f_tex_读写布局(face->m_Color[0]);
	f_tex_读写布局(face->m_Color[1]);

	face->m_Color[2] = nullptr;
	face->m_Color[3] = nullptr;
	face->m_Color[4] = nullptr;

	face->m_帧缓存 = f_fb_创建3D场景帧缓存(Ctx3D, size, face->m_Color[0], face->m_Depth[0]);
	face->m_帧缓存->m_颜色通道数量 = 1;
	face->m_帧缓存->m_深度通道数量 = 1;

	auto pipeline = dc->m_2D渲染管线->m_计算管线_图像合成;

	face->m_DS = new C_VkDescriptorSet(pipeline->m_Pipeline, pipeline->m_Shader);
	face->m_合成纹理绑定槽 = f_纹理槽_创建(1);
	face->m_平面绑定纹理集 = f_纹理集_创建(3);

	f_纹理集_set纹理(face->m_平面绑定纹理集, face->m_Color[0], 0);
	f_纹理集_set纹理(face->m_平面绑定纹理集, face->m_Color[1], 1);
	f_纹理集_set纹理(face->m_平面绑定纹理集, face->m_Depth[0], 2);

	return face;
}

void f_surface3D_重置大小(S_Surface3D* surf, uvec2 size) {
	f_df_钳制视口大小(*surf->m_Ctx, size);
	//size /= 16;
	//size *= 16;
	//size += 16;

	if(surf->m_帧缓存->m_Size == size) return;

	f_tex_修改大小(surf->m_Color[0], _uVec3(size, 1), false);
	f_tex_修改大小(surf->m_Color[1], _uVec3(size, 1), false);
	f_tex_修改大小(surf->m_Depth[0], _uVec3(size, 1), false);

	S_纹理* tex[2] = { surf->m_Color[0], surf->m_Depth[0] };
	f_fb_重置3D场景帧缓存(surf->m_帧缓存, size, tex);
}



S_Frame2D* f_surface_创建平面帧(S_设备环境& ctx, const uvec2& size) {
	S_Frame2D* face = (S_Frame2D*)malloc(sizeof(S_Frame2D));
	face->m_纹理采样器 = f_tex_创建纹理采样器(ctx);

	face->m_Color[0] = f_tex_创建帧缓存图像(ctx, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_MS次数::e_MS_1);
	face->m_Color[1] = f_tex_创建帧缓存图像(ctx, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_MS次数::e_MS_1);
	//face->m_Color[2] = f_tex_创建帧缓存图像(ctx, { size.x >> 2, size.y >> 2, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_MS次数::e_MS_1);
	

	f_tex_读写布局(face->m_Color[0]);
	f_tex_读写布局(face->m_Color[1]);
	//f_tex_采样布局(face->m_Color[2]);

	face->m_帧缓存 = f_fb_创建UI渲染帧缓存(ctx, size, face->m_Color);
	face->m_帧缓存->m_颜色通道数量 = 2;
	face->m_帧缓存->m_深度通道数量 = 0;

	f_tex_安装纹理采样器(face->m_Color[0], face->m_纹理采样器);
	f_tex_安装纹理采样器(face->m_Color[1], face->m_纹理采样器);

	return face;
}

void f_surface_销毁平面帧(S_Frame2D* face) {
	f_tex_销毁纹理(face->m_Color[0]);
	f_tex_销毁纹理(face->m_Color[1]);

	f_fb_销毁帧缓存(face->m_帧缓存);
	free(face);
}

void f_surface_重置平面帧大小(S_设备环境& ctx, S_Frame2D* face, const uvec2& size) {
	f_tex_修改大小(face->m_Color[0], _uVec3(size, 1), false);
	f_tex_修改大小(face->m_Color[1], _uVec3(size, 1), false);

	f_fb_重置UI渲染帧缓存(ctx, face->m_帧缓存, size, face->m_Color);
}

bool f_surface_改变大小(S_Surface3D* face, const uvec2& size, bool 创建单层输出) {
	if (size.x <= 0 || size.y <= 0) {
		std::cout << "err: 改变面纹理大小小于最小大小" << std::endl;
	}
	if (face->m_Color[0]->m_Size.x == size.x && face->m_Color[0]->m_Size.y == size.y) {
		return false;
	}
	

	face->m_交换ID = 0;
	face->m_帧缓存->f_release(false);
	face->m_帧缓存->m_Size = size;
	

	f_tex_setSize(face->m_Color[0], size);
	if (创建单层输出) {
		f_bd_构建帧缓存纹理(*face->m_Ctx, face->m_帧缓存, size, face->m_Color, 1);
	}
	else {
		f_tex_setSize(face->m_Color[1], size);
		f_tex_setSize(face->m_Color[2], size);

		f_bd_构建帧多重采样缓存(*face->m_Ctx, face->m_帧缓存, size, face->m_Color, 2);
	}
	return true;
}

void f_surface_set采样(S_Surface3D* face, E_MS次数 采样) {
	auto* 绘图环境 = f_vk_get绘图环境(*face->m_Ctx);

	if (绘图环境->m_设备属性.limits.sampledImageColorSampleCounts >= 采样<<1) {
		face->m_Ctx->m_采样数 = 采样;
	}
	else {
		return;
	}

	S_Vk帧缓存* vf = (S_Vk帧缓存*)face->m_帧缓存;

	vf->m_渲染通道 = f_创建纹理渲染通道(绘图环境->m_设备, f_vk_getVK图像格式(face->m_Color[0]->m_格式), f_vk_getVK图像格式(E_纹理格式::e_tf_D32F), 采样);
	//绘图设备配置->m_开始渲染信息.renderPass = 绘图设备配置->m_渲染通道;
	//绘图设备配置->m_二级命令缓存继承信息.renderPass = 绘图设备配置->m_渲染通道;

	face->m_交换ID = 0;
	face->m_帧缓存->f_release();

	if (face->m_帧缓存->m_颜色图像) {
		f_tex_销毁纹理(face->m_帧缓存->m_颜色图像);
		face->m_帧缓存->m_颜色图像 = nullptr;
	}

	f_bd_构建帧多重采样缓存(*face->m_Ctx, face->m_帧缓存, face->m_帧缓存->m_Size, face->m_Color, 2);
}

void f_surface_创建G缓存(S_Surface3D* face) {
	S_纹理* 顶点 = f_tex_创建图像纹理(*face->m_Ctx, { 2,2,1 }, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);
	S_纹理* 法线 = f_tex_创建图像纹理(*face->m_Ctx, {2,2,1}, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);

	f_tex_安装纹理采样器(顶点, S_全局缓存::g_默认采样器);
	f_tex_安装纹理采样器(法线, S_全局缓存::g_默认采样器);

}


S_Surface3D* f_surface_CreateCube(S_设备环境& Ctx3D, uvec2 size, uvec2 渲染大小, S_纹理采样器* 采样器, uint8 层级数量) {
	S_Surface3D* face = f_surface_Create(Ctx3D);
	face->m_纹理数量 = 层级数量;
	//face->m_纹理数量 = 1;

	face->m_Color[0] = f_tex_创建帧缓存纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_CUBE);
	face->m_Depth[0] = f_tex_创建深度纹理(Ctx3D, { size.x, size.y, 1 }, E_MS次数::e_MS_1, E_纹理维度类型::e_CUBE);

	f_tex_创建独立纹理视图(face->m_Color[0], true);
	f_tex_创建独立纹理视图(face->m_Depth[0], false);

	f_tex_安装纹理采样器(face->m_Color[0], 采样器);
	f_tex_安装纹理采样器(face->m_Depth[0], 采样器);

	层级数量 = min(层级数量, 6);
	for (uint32 i = 1; i < 层级数量; ++i) {
		size /= 2;
		face->m_Color[i] = f_tex_创建图像纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_CUBE);

		f_tex_安装纹理采样器(face->m_Color[i], 采样器);
		f_tex_创建独立纹理视图(face->m_Color[i], true);

	}

	face->m_帧缓存 = f_fb_创建立方体帧缓存(Ctx3D, 渲染大小, face->m_Color[0], face->m_Depth[0]);
	f_tex_立方体纹理深度布局(face->m_Depth[0], 6);
	return face;
}

bool f_surface_Cube改变大小(S_Surface3D* face, uvec2 size) {
	if (face->m_Color[0]->m_Size.x == size.x && face->m_Color[0]->m_Size.y == size.y) {
		return false;
	}
	f_tex_setSize(face->m_Color[0], size);
	f_tex_setSize(face->m_Depth[0], size);

	f_tex_创建独立纹理视图(face->m_Color[0], true);
	f_tex_创建独立纹理视图(face->m_Depth[0], false);

	f_fb_重置立方体帧缓存(face->m_帧缓存, size);

	face->m_纹理数量 = min(face->m_纹理数量, 6);
	for (uint32 i = 1; i < face->m_纹理数量; ++i) {
		size /= 2;
		f_tex_setSize(face->m_Color[i], size);

		f_tex_创建独立纹理视图(face->m_Color[i], true);
	}

	f_tex_立方体纹理深度布局(face->m_Depth[0], 0);
	
	return false;
}

bool f_surface_3D改变大小(S_Surface3D* face, uvec2 size) {
	if (face->m_Color[0]->m_Size.x == size.x && face->m_Color[0]->m_Size.y == size.y) {
		return false;
	}

	f_tex_setSize(face->m_帧缓存->m_颜色图像, size);
	f_tex_setSize(face->m_帧缓存->m_深度图像, size);

	f_tex_setSize(face->m_Color[0], size);



	f_fb_重置合成帧缓存(face->m_帧缓存, size);
	return false;
}


S_Surface3D* f_surface_Create几何缓存(S_设备环境& Ctx3D, const uvec2& size) {
	S_Surface3D* face = f_surface_Create(Ctx3D);
	face->m_纹理数量 = 2;

	face->m_Color[0] = f_tex_创建帧缓存纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);
	face->m_Color[1] = f_tex_创建帧缓存纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA32, E_纹理维度类型::e_2D);
	face->m_Depth[0] = f_tex_创建深度纹理(Ctx3D, { size.x, size.y, 1 }, E_MS次数::e_MS_1, E_纹理维度类型::e_2D);

	f_tex_安装纹理采样器(face->m_Color[0], f_g_纹理().g_颜色纹理采样器);
	f_tex_安装纹理采样器(face->m_Color[1], f_g_纹理().g_颜色纹理采样器);
	f_tex_安装纹理采样器(face->m_Depth[0], f_g_纹理().g_阴影采样器);

	f_tex_set纹理颜色附件布局(face->m_Color[0], 1);
	f_tex_set纹理颜色附件布局(face->m_Color[1], 1);

	face->m_帧缓存 = f_fb_创建几何缓存帧缓存(Ctx3D, size, face->m_Color, face->m_Depth[0], face->m_纹理数量);
	return face;
}

bool f_surface_set几何缓存分辨率(S_Surface3D* face, uvec2 size) {
	if (face->m_Color[0]->m_Size.x == size.x && face->m_Color[0]->m_Size.y == size.y) {
		return false;
	}

	for (uint32 i = 0; i < face->m_纹理数量; ++i) {
		f_tex_setSize(face->m_Color[i], size);
	}
	f_tex_setSize(face->m_Depth[0], size);

	f_fb_重置几何缓存帧缓存(face->m_帧缓存, size);
	return false;
}

bool f_surface_set渲染纹理(S_Surface3D* face, uint32 内部纹理ID) {
	
	return false;
}



void f_surface_setG缓存纹理大小(S_Surface3D* face, uvec2 size) {
	//f_tex_修改大小(face->m_GBuffer[0], size);
	//f_tex_修改大小(face->m_GBuffer[1], size);
}

void f_surface_Release(S_Surface3D* face) {
	
	for (uint32 i = 0; i < face->m_纹理数量; ++i) {
		f_tex_销毁纹理(face->m_Color[i]);
	}

	face->m_帧缓存->f_release();

	delete face->m_DS;
}

void f_surface_改变纹理用途(S_Surface3D* face, E_纹理用途布局 用途) {
	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)face->m_Ctx->m_绘图环境;

	auto cmd = f_vk创建命令缓存(绘图设备配置);
	f_vk绑定命令缓存(绘图设备配置, cmd);
	
	for (uint32 i = 0; i < face->m_纹理数量; ++i) {
		S_VkImage* 图像 = (S_VkImage*)(face->m_Color[i]);
	
		switch (用途) {
			//case E_纹理用途布局::e_帧附件:
			case E_纹理用途布局::e_采样: {
				
				if (图像->m_Cube纹理信息) {
					//for (uint32 i = 0; i < 6; ++i) {
					//	f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_Cube纹理信息[i].imageLayout, VK_IMAGE_LAYOUT_GENERAL, 1, i);
					//	//f_vkImage_着色器读写布局(cmd, 图像->m_Image, 图像->m_ImageAspect, 1, i);
					//	图像->m_Cube纹理信息[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
					//}
				}
				else {
					
					//f_vkImage_帧缓存布局(cmd, 图像->m_Image, 图像->m_ImageAspect, 1);
				}
				//f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_纹理信息[0].imageLayout, VK_IMAGE_LAYOUT_GENERAL, 1);
				//图像->m_纹理信息[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
				
				break;
			}
			case E_纹理用途布局::e_帧附件: {
			
				if (图像->m_Cube纹理信息) {
					for (uint32 i = 0; i < 6; ++i) {
						f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_Cube纹理信息[i].imageLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, i);
						//f_vkImage_帧缓存布局(cmd, 图像->m_Image, 图像->m_ImageAspect, 1, i);
						图像->m_Cube纹理信息[i].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
					}
				}
				else {
					f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_纹理信息.imageLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1);
					//f_vkImage_帧缓存布局(cmd, 图像->m_Image, 图像->m_ImageAspect, 1);
				}
				
				图像->m_纹理信息.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
				break;
			}
		}
	}

	for (uint32 i = 0; i < face->m_纹理数量; ++i) {
		S_VkImage* 图像 = (S_VkImage*)(face->m_Depth[i]);

		
		switch (用途) {
			case E_纹理用途布局::e_采样: {
				
				//if (图像->m_Cube纹理信息) {
				//	for (uint32 i = 0; i < 6; ++i) {
				//		f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_Cube纹理信息[i].imageLayout, VK_IMAGE_LAYOUT_GENERAL, 1, i);
				//		图像->m_Cube纹理信息[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
				//	}
				//}
				//else {
				//	f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_纹理信息[0].imageLayout, VK_IMAGE_LAYOUT_GENERAL, 1);
				//}
				//图像->m_纹理信息[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
				break;
			}
				
			case E_纹理用途布局::e_帧附件: {
				//if(图像->m_纹理信息[0].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) break;

				if (图像->m_Cube纹理信息) {
					for (uint32 i = 0; i < 6; ++i) {
						f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_Cube纹理信息[i].imageLayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, i);
						图像->m_Cube纹理信息[i].imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
					}
				}
				else {
					f_vkImage_setLayout(cmd, 图像->m_Image, 图像->m_ImageAspect, 图像->m_纹理信息.imageLayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1);
				}
				图像->m_纹理信息.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
				break;
			}
				
			default:
				break;
		}
		
	}

	f_vk刷新命令缓存(绘图设备配置, cmd, true);
}





S_Widget绘制材质::S_Widget绘制材质(S_设备环境& Ctx, E_MS次数 msCount) {
	m_采样器 = f_tex_创建纹理采样器(Ctx);
	std::cout << "shader file path : " << S_引擎配置::m_UI着色器文件根路径 << std::endl;
	return;
}

S_Widget绘制材质::~S_Widget绘制材质() {
	//f_df_销毁材质着色器(m_线段);
}








S_UI渲染环境::S_UI渲染环境(S_设备环境& ctx, E_MS次数 msCount) : m_Ctx(ctx) {
	assert(m_预设图元顶点.size());

	if (!glibrary) {
		FT_Error err = FT_Init_FreeType(&glibrary);
		if (err) {
			std::cout << "初始化freetype2失败" << std::endl;
		}
	}

	m_采样数 = msCount;
	m_DPI = 1;
	m_窗口DPI = 1;



	m_纹理槽 = f_纹理槽_创建(2);
	m_平面绑定纹理集 = f_纹理集_创建((DEF_UI_LayerNum + 1) * 3);
	m_方体绑定纹理集 = f_纹理集_创建((DEF_UI_LayerNum + 1) * 3);

	std::vector<S_纹理*> 填充纹理((DEF_UI_LayerNum + 1) * 3, S_全局缓存::g_空纹理);
	f_纹理集_fill纹理(m_平面绑定纹理集, 填充纹理);

	std::vector<S_纹理*> 填充方体纹理((DEF_UI_LayerNum + 1) * 3, f_g_纹理().g_缺损方体纹理);
	f_纹理集_fill纹理(m_方体绑定纹理集, 填充方体纹理);

	f_纹理槽_设置纹理集(m_纹理槽, m_平面绑定纹理集, 0, DEF_binding_L4_TexArray);
	f_纹理槽_设置纹理集(m_纹理槽, m_方体绑定纹理集, 1, DEF_binding_L4_TexCube);

	m_更新纹理绑定 = true;

	m_GM = nullptr;

	m_层区域采样属性.resize(DEF_UI_LayerAreaNum);
	memset(m_层区域采样属性.data(), 0, sizeof(S_FrameSample_TAA) * DEF_UI_LayerAreaNum);

	m_层区域属性 = f_buf_create板载缓存(m_Ctx, sizeof(S_FrameSample_TAA), E_板载缓存类型::e_UBO, DEF_UI_LayerAreaNum);
	f_buf_fill(m_层区域属性, 0, m_层区域采样属性.data(), sizeof(S_FrameSample_TAA) * DEF_UI_LayerAreaNum);


	auto& 合成管线 = ctx.m_绘图环境->m_2D渲染管线->m_管线_图像合成->m_UI合成线管;
	m_DS_UI图层纹理混合 = new C_VkDescriptorSet(合成管线->m_Pipeline, 合成管线->m_Shader);
	//m_DS_合成 = new C_VkDescriptorSet(ctx.m_绘图环境->m_2D渲染管线->m_管线_UI合成->m_UI合成线管);

}

S_UI渲染环境::~S_UI渲染环境() {
	delete m_DS_UI图层纹理混合;

	f_纹理集_销毁(m_平面绑定纹理集);
	f_纹理集_销毁(m_方体绑定纹理集);

	f_纹理槽_销毁(m_纹理槽);
	//delete m_DS_合成;
}

uint32 S_UI渲染环境::f_Bind_纹理(S_纹理* tex) {
	
	uint32 id = f_纹理集_find纹理(m_平面绑定纹理集, S_全局缓存::g_空纹理);
	if (id >= m_平面绑定纹理集->data->count) {
		id = m_平面绑定纹理集->data->count;
		f_纹理集_add纹理(m_平面绑定纹理集, tex);
	}
	else {
		f_纹理集_set纹理(m_平面绑定纹理集, tex, id);
	}

	m_更新纹理绑定 = true;
	return id;
}

void S_UI渲染环境::f_UpBind_纹理(S_纹理* tex) {
	uint32 id = f_纹理集_find纹理(m_平面绑定纹理集, tex);
	if (id < m_平面绑定纹理集->data->count) {
		f_纹理集_set纹理(m_平面绑定纹理集, S_全局缓存::g_空纹理, id);
	}
}

void S_UI渲染环境::f_update_纹理绑定() {
	if (m_更新纹理绑定) {
		f_纹理集_刷新所有纹理信息(m_平面绑定纹理集);
		f_纹理槽_设置纹理集(m_纹理槽, m_平面绑定纹理集, 0, DEF_binding_L4_TexArray);

		f_纹理集_刷新所有纹理信息(m_方体绑定纹理集);
		f_纹理槽_设置纹理集(m_纹理槽, m_方体绑定纹理集, 1, DEF_binding_L4_TexCube);
	}
}

void S_UI渲染环境::f_渲染图层混合(std::vector<mat2>& vert) {
	//f_vg_set2DView(m_Ctx, {{}, {m_Size.x, m_Size.y}}, nullptr);


}

void S_UI渲染环境::f_准备图层渲染() {
	m_层区域采样属性.clear();
	m_层区域采样属性.reserve(DEF_UI_LayerAreaNum);
}



void S_UI渲染环境::f_初始化预设图元() {
	m_预设图元顶点.clear();
	
	m_图元ID.m_矩形 = f_vg_生成矩形顶点<S_2D图元顶点>(m_预设图元顶点);
	m_图元ID.m_左圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_左);
	m_图元ID.m_右圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_右);
	m_图元ID.m_上圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_上);
	m_图元ID.m_下圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_下);
	m_图元ID.m_圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_中);
	m_图元ID.m_左上圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_左上);
	m_图元ID.m_右上圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_右上);
	m_图元ID.m_竖向圆角连接线 = f_vg_生成圆角连接线顶点(m_预设图元顶点, E_方向::e_纵向);
	m_图元ID.m_横向圆角连接线 = f_vg_生成圆角连接线顶点(m_预设图元顶点, E_方向::e_横向);
	m_图元ID.m_横线 = f_vg_生成直线顶点(m_预设图元顶点, E_方向::e_横向);
	m_图元ID.m_竖线 = f_vg_生成直线顶点(m_预设图元顶点, E_方向::e_纵向);
	m_图元ID.m_斜线 = f_vg_生成直线顶点(m_预设图元顶点, E_方向::e_中);
	m_图元ID.m_生成C形左拐角连接线 = f_vg_生成C形拐角连接线顶点(m_预设图元顶点, E_方向::e_左);
	m_图元ID.m_生成C形左拐角连接线 = f_vg_生成C形拐角连接线顶点(m_预设图元顶点, E_方向::e_左);
	m_图元ID.m_生成L形下拐角连接线 = f_vg_生成L形拐角连接线顶点(m_预设图元顶点, E_方向::e_下);
	m_图元ID.m_生成L形上拐角连接线 = f_vg_生成L形拐角连接线顶点(m_预设图元顶点, E_方向::e_上);

	S_Widget预设凸包图元::m_圆形 = f_vg_生成圆形顶点(m_预设图元顶点);
}

void S_UI渲染环境::f_销毁绘图资源() {
	
}


//void S_UI渲染环境::f_创建预设图元() {
//	S_2D画布::g预设_矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_圆形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_左圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_右圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_上圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_下圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_左上圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_右上圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_左下圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//	S_2D画布::g预设_右下圆角矩形 = f_bm_alloc(f_buf_getGlobal().g_凸包图元, 0);
//
//
//	std::vector<S_2D图元顶点> vert;
//	f_vg_生成矩形顶点<S_2D图元顶点>(vert);
//	f_bm_push_back(S_2D画布::g预设_矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_中);
//	f_bm_push_back(S_2D画布::g预设_圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_左);
//	f_bm_push_back(S_2D画布::g预设_左圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_右);
//	f_bm_push_back(S_2D画布::g预设_右圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_上);
//	f_bm_push_back(S_2D画布::g预设_上圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_下);
//	f_bm_push_back(S_2D画布::g预设_下圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_左上);
//	f_bm_push_back(S_2D画布::g预设_左上圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_左下);
//	f_bm_push_back(S_2D画布::g预设_左下圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_右上);
//	f_bm_push_back(S_2D画布::g预设_右上圆角矩形, vert.data(), vert.size());
//
//	vert.clear();
//	f_vg_生成方向圆角矩形顶点(vert, E_方向::e_右下);
//	f_bm_push_back(S_2D画布::g预设_右下圆角矩形, vert.data(), vert.size());
//}

//void S_UI渲染环境::f_销毁预设图元() {
//	
//}




S_2D画布::S_2D画布(S_设备环境& ctx) : m_Ctx(ctx) {
	//auto* rf = f_vk_get绘图框架(ctx);
	m_变换 = f_bm_alloc(ctx.m_几何图形->m_2D面板变换G, 1);
	m_父级画布属性 = nullptr;
	m_是否重绘 = true;


	m_绘制推进层 = 0;
}

S_2D画布::~S_2D画布() {
	f_bm_erase(m_变换);


	for (auto& s : m_surf)			f_surface2D_release(&s);
	for (auto& e : m_扩展GPU参数)	f_buf_release板载缓存(e);
	for (auto& e : m_属性)			f_buf_release板载缓存(e);

	m_surf.clear();
	m_属性.clear();
	m_扩展GPU参数.clear();
}

void S_2D画布::f_清除绘制数据() {
	m_绘制推进层 = 0;
	for (auto& obj : m_surf) {
		f_surface2D_release(&obj);
	}
	m_surf.clear();
}

//void S_2D画布::f_绘制到屏幕(S_渲染参数& 参数) {
//	S_渲染参数 渲染参数 = 参数;
//}




static S_iRect f_surface_加载字纹理遮罩(FT_Face& f, wchar_t 编码, uint16 字号, uint32 rowNum, uint8* data) {
	auto glyph_index = FT_Get_Char_Index(f, 编码);
	S_iRect area = {};
		
	auto err = FT_Load_Glyph(f, glyph_index, FT_LOAD_DEFAULT);
	err = FT_Render_Glyph(f->glyph, FT_RENDER_MODE_NORMAL);
	if (!err) {
		uint16 高度 = DEF_Min(uint16(字号 - 1), f->glyph->bitmap.rows);
		uint16 宽度 = DEF_Min(uint16(字号 - 1), f->glyph->bitmap.width);

		for (uint16 y = 0; y < 高度; ++y) {
			for (uint16 x = 0; x < 宽度; ++x) {
				uint32 offset = (x + 1) + (rowNum * (y + 1));
				data[offset] = f->glyph->bitmap.buffer[f->glyph->bitmap.width * y + x];
				//f->glyph->bitmap.buffer[f->glyph->bitmap.width * y + x];
			}
		}


		area.左边 = f->glyph->bitmap_left;
		area.顶边 = f->size->metrics.ascender / 64 - f->glyph->bitmap_top;
		//area.顶边 = f->glyph->bitmap_top;
		area.宽度 = f->glyph->bitmap.width;
		area.高度 = f->glyph->bitmap.rows;
	}

	return area; 
}



void f_surface2D_release(S_Surface2D* surf) {

	if (surf->m_纹理槽.m_槽数量) {
		f_纹理槽_销毁(surf->m_纹理槽);
	}

	if (surf->m_笔刷.m_参数元素数量) {
		free(surf->m_笔刷.m_参数槽);
		free(surf->m_笔刷.m_绑定位置);
	}
	surf->m_笔刷.m_参数元素数量 = 0;

	if (surf->m_笔刷.m_纹理信息 != nullptr && surf->m_笔刷.m_纹理参数数量) free(surf->m_笔刷.m_纹理信息);
	surf->m_笔刷.m_纹理参数数量 = 0;

	surf->m_笔刷.m_参数槽 = nullptr;
	surf->m_笔刷.m_纹理信息 = nullptr;
	
	if(surf->m_自定义属性) free(surf->m_自定义属性);
	

	if (!surf->m_顶点引用) f_bm_erase(surf->m_顶点);
	if (!surf->m_索引引用) f_bm_erase(surf->m_索引);
	if (!surf->m_间接引用) f_bm_erase(surf->m_间接);
	(*surf) = {};
}

void f_surface_创建2D绘制预设形状缓存(S_设备环境& ctx) {
	auto* df = f_vk_get绘图框架(ctx);

	ctx.m_几何图形->m_平面矩形			= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面圆角矩形		= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面左圆角矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面右圆角矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面上圆角矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面下圆角矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面左上角矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面左下角矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面下右上矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面下右下矩形	= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面圆形			= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面横向直线		= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);
	ctx.m_几何图形->m_平面纵向直线		= f_bm_alloc(ctx.m_几何图形->m_平面图形GPU缓存_顶点, 0);



	std::vector<mat2> 预设图元顶点;
	f_vg_生成矩形顶点<mat2>(预设图元顶点);
	f_bm_push_back(ctx.m_几何图形->m_平面矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_中);
	f_bm_push_back(ctx.m_几何图形->m_平面圆角矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_左);
	f_bm_push_back(ctx.m_几何图形->m_平面左圆角矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_右);
	f_bm_push_back(ctx.m_几何图形->m_平面右圆角矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_上);
	f_bm_push_back(ctx.m_几何图形->m_平面上圆角矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_下);
	f_bm_push_back(ctx.m_几何图形->m_平面下圆角矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_左上);
	f_bm_push_back(ctx.m_几何图形->m_平面左上角矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_左下);
	f_bm_push_back(ctx.m_几何图形->m_平面左下角矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_右上);
	f_bm_push_back(ctx.m_几何图形->m_平面下右上矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成方向圆角矩形顶点(预设图元顶点, E_方向::e_右下);
	f_bm_push_back(ctx.m_几何图形->m_平面下右下矩形, 预设图元顶点.data(), 预设图元顶点.size());

	预设图元顶点.clear();
	f_vg_生成圆形顶点(预设图元顶点);
	f_bm_push_back(ctx.m_几何图形->m_平面圆形, 预设图元顶点.data(), 预设图元顶点.size());


	预设图元顶点.clear();
	f_vg_生成直线顶点(预设图元顶点, E_方向::e_横向);
	f_bm_push_back(ctx.m_几何图形->m_平面横向直线, 预设图元顶点.data(), 预设图元顶点.size());
	预设图元顶点.clear();
	f_vg_生成直线顶点(预设图元顶点, E_方向::e_纵向);
	f_bm_push_back(ctx.m_几何图形->m_平面纵向直线, 预设图元顶点.data(), 预设图元顶点.size());


	ctx.m_几何图形->m_平面矩形;
}

void f_surface_销毁2D绘制预设形状缓存(S_设备环境& ctx) {
	f_buf_release板载缓存(ctx.m_几何图形->m_平面图形GPU缓存_顶点);

}

void f_alloc_笔刷槽数量(S_2D笔刷& 笔刷, uint32 num) {
	笔刷.m_参数元素数量 = num;
	笔刷.m_参数槽 = (void**)calloc(笔刷.m_参数元素数量, sizeof(void*));
	笔刷.m_绑定位置 = (uint8*)calloc(笔刷.m_参数元素数量, sizeof(uint8));
	笔刷.m_参数类型 = (uint32*)calloc(笔刷.m_参数元素数量, sizeof(uint32));

	笔刷.m_纹理信息 = nullptr;
	笔刷.m_纹理参数数量 = 0;

	//memcpy(笔刷.m_参数元素,)
	for (uint32 i = 0; i<num; ++i) {
		笔刷.m_参数槽[i] = nullptr;
		笔刷.m_绑定位置[i] = 0;
		笔刷.m_参数类型[i] = 0;
	}
}

void f_surface_加载字体(S_UI渲染环境& ctx, const S_字体加载参数& 字体参数) {
	FT_Face face;
	auto err = FT_New_Face(glibrary, 字体参数.m_字体文件路径.c_str(), 0, &face);
	err = FT_Set_Pixel_Sizes(face, 字体参数.m_字号, 字体参数.m_字号);
	err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
	
	
	std::string name = 字体参数.m_名称 + "_" + f_整数值转字符串(字体参数.m_字号);
	if (name.empty()) {
		name = 字体参数.m_字体文件路径 + "_" + f_整数值转字符串(字体参数.m_字号);
	}

	ctx.m_Mat->m_Fonts[name] = S_Font();
	auto& font = ctx.m_Mat->m_Fonts[name];
	font.m_字体名称 = name;

	uvec2 纹理大小 = { 2048, 1 };
	纹理大小.x = ((S_物理设备属性*)ctx.m_Ctx.m_物理设备.物理设备属性)->m_3D纹理最大分辨率;

	
	font.m_字号 = 字体参数.m_字号;
	uint64 字体大小 = 字体参数.m_字号 + 2;
	

	std::vector<wchar_t>	外部编码(65536);
	std::vector<ivec4>		UV;

	uint64 字符总数量 = 0;
	uint32 offset_r = 0;
	for (auto& e : 字体参数.m_编码区间) {
		
		for (uint32 i = e.x; i < e.y; ++i) {
			外部编码[i] = i;
		}
	}
	字符总数量 = 65536;
	

	uvec2 字符纹理分割 = { 纹理大小.x / 字体大小 };
	字符纹理分割.y = 字符纹理分割.x;
	
	

	纹理大小.x = 字符纹理分割.x * 字体大小;
	纹理大小.y = 字符纹理分割.y * 字体大小;

	uint64 每层纹理中字符个数 = 字符纹理分割.x * 字符纹理分割.y;
	uint64 每层纹理像素数量 = uint64(纹理大小.x * 纹理大小.y );
	uint64 纹理张数 = DEF_Max(字符总数量 / 每层纹理中字符个数, 1);
	
	std::vector<uint8> data(纹理张数 * 每层纹理像素数量);
	font.m_区域.resize(65536 + 1);



	//UV数据 第一个存储公共信息 (字符高度)
	UV.resize(uint64(字符总数量 + 1));
	

	auto* p_外部编码 = 外部编码.data();
	auto* p_UV = UV.data();
	auto* p_rect = font.m_区域.data();

//#pragma omp parallel for
	for (int32 纹理层ID = 0; 纹理层ID < 纹理张数; ++纹理层ID) {
		std::vector<uint8> tempData(每层纹理像素数量);

		for (int32 y = 0; y < 字符纹理分割.y; ++y) {

			//#pragma omp parallel for
			for (int32 x = 0; x < 字符纹理分割.x; ++x) {
				uint64 X = 字体大小 * x;
				uint64 Y = 纹理大小.x * (字体大小 * y);
				uint64 Z = 每层纹理像素数量 * 纹理层ID;
				

				uint64 i = uint64((每层纹理中字符个数 * 纹理层ID) + (字符纹理分割.x * y) + x);
				uint64 offset = Y + X;

				if (i < 字符总数量) {
					
					if (p_外部编码[i]) {
						p_rect[i] = f_surface_加载字纹理遮罩(face, p_外部编码[i], 字体大小, 纹理大小.x, &tempData[offset]);

						//========= ++i p_UV第一个需要左全局属性 ,所以 p_rect --i =========
						p_UV[i].x = x;
						p_UV[i].y = y;

						if (p_外部编码[i] == L' ') {
							p_rect[i].宽度 = uint32(字体大小 >> 1);

							p_UV[i].z = 纹理层ID | (uint32(p_rect[i].宽度) << 16);
							p_UV[i].w = 1;

							
						}
						else {
							p_UV[i].z = 纹理层ID | (uint32(p_rect[i].宽度) << 16);
							p_UV[i].w = p_rect[i].顶边 | (uint32(p_rect[i].左边) << 16);
						}
					}
					else {
						p_rect[i] = {};
						p_UV[i] = {};
					}
				}
			}
		}

		uint64 offset = 每层纹理像素数量 * 纹理层ID;
		//uint64 offset = data.size();
		//data.resize(offset + 每层纹理像素数量);
		memcpy(&(data[offset]), tempData.data(), 每层纹理像素数量 * sizeof(uint8));

	}

	To_结束循环加载:
	UV[0].x = float32(字体大小) / 纹理大小.x;
	UV[0].y = 字体大小;



	uvec3 纹理维度 = { 纹理大小.x , 纹理大小.y , 纹理张数 };
	font.m_Tex = f_tex_创建图像纹理(ctx.m_Ctx, 纹理维度, E_纹理格式::e_tf_R8U_归一化, E_纹理维度类型::e_2D_Array);
	f_tex_填充纹理数据(font.m_Tex, data.data(), sizeof(uint8), 纹理维度);
	f_tex_安装纹理采样器(font.m_Tex, ctx.m_Mat->m_采样器);
	

	font.m_uv偏移 = f_buf_create板载缓存(ctx.m_Ctx, sizeof(ivec4));
	f_buf_fill板载缓存(font.m_uv偏移, UV, E_板载缓存类型::e_SSBO);

	font.m_字符UV = f_bm_alloc(f_buf_getGlobal().g_字符纹理UV, UV.size());
	f_gbuf_fill(font.m_字符UV, UV.data(), 0, UV.size());
	
	return;
}

void f_surface_加链字体纹理(S_设备环境& ctx, S_字体& 字体, const S_字体加载参数& 字体参数, const std::u16string& txt) {
	if(!txt.size()) return;

	FT_Face face;
	auto err = FT_New_Face(glibrary, 字体参数.m_字体文件路径.c_str(), 0, &face);
	if(err) {
		std::cout << "error: 加载字体失败" << 字体参数.m_字体文件路径 << std::endl;
		return;
	}
	err = FT_Set_Pixel_Sizes(face, 字体参数.m_字号, 字体参数.m_字号);
	err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);

	uvec2 纹理大小 = { 2048, 1 };
	纹理大小.x = ((S_物理设备属性*)ctx.m_物理设备.物理设备属性)->m_3D纹理最大分辨率;



	uint64 字体大小 = 字体参数.m_字号 + 2;
	uint64 字符总数量 = txt.size();

	uvec2 字符纹理分割 = { 纹理大小.x / 字体大小, 纹理大小.x / 字体大小 };

	字符纹理分割.x = DEF_Min(字符纹理分割.x, 字符总数量);

	uint32 行数 = 字符总数量 / 字符纹理分割.x;
	字符纹理分割.y = DEF_Min(行数, 字符纹理分割.x);

	uint32 纹理张数 = DEF_Max(字符总数量 / (字符纹理分割.x * 字符纹理分割.y), 1);


	纹理大小.x = (字符纹理分割.x * 字体大小);
	纹理大小.y = (字符纹理分割.y * 字体大小);

	uint64 每层纹理中字符个数 = 字符纹理分割.x * 字符纹理分割.y;
	uint64 每层纹理像素数量 = uint64(纹理大小.x * 纹理大小.y);
	std::vector<uint8> FillData(纹理张数 * 每层纹理像素数量);

//	omp_set_num_threads(4);
//	#pragma omp parallel for 
	for (int32 纹理层ID = 0; 纹理层ID < 纹理张数; ++纹理层ID) {
		uint64 Z = 每层纹理像素数量 * 纹理层ID;

		std::vector<uint8> tempData(每层纹理像素数量);


		for (int32 y = 0; y < 字符纹理分割.y; ++y) {
			for (uint32 x = 0; x < 字符纹理分割.x; ++x) {
				uint64 X = 字体大小 * x;
				uint64 Y = 纹理大小.x * (字体大小 * y);
				
				uint64 每一层每个字符像素偏移 = Y + X;
				uint64 每个字符ID = uint64((每层纹理中字符个数 * 纹理层ID) + (字符纹理分割.x * y) + x);


				if (每个字符ID < 字符总数量) {
					auto 字符 = txt.at(每个字符ID);
					auto r = f_surface_加载字纹理遮罩(face, 字符, 字体大小, 纹理大小.x, &tempData[每一层每个字符像素偏移]);
					字体.m_区域[字符] = r;

					//字体.m_uv偏移[字符] = { r.左边, r.顶边, float32(纹理层ID) };
					字体.m_uv偏移[字符] = { float32(x* 字体大小), float32(y * 字体大小), float32(纹理层ID) };
					字体.m_字符大小[字符] = { float32(r.宽度), float32(r.高度) };
				}
			}
		}

		uint64 offset = 每层纹理像素数量 * 纹理层ID;
		memcpy(&(FillData[offset]), tempData.data(), 每层纹理像素数量 * sizeof(uint8));
	}

	字体.m_字符大小[' '].x = 字体参数.m_字号/2;

	static S_纹理采样器* 采样器 = f_tex_创建纹理采样器(ctx);

	uvec3 纹理维度 = { 纹理大小.x , 纹理大小.y , 纹理张数 };
	f_tex_修改大小(字体.m_Tex, 纹理维度, false);
	f_tex_填充纹理数据(字体.m_Tex, FillData.data(), sizeof(uint8), 纹理维度);
	f_tex_安装纹理采样器(字体.m_Tex, 采样器);

	字体.m_字号 = 字体大小;

	FT_Done_Face(face);
}

uint16 f_surface_get字符串宽度T(const S_Font& font, std::u16string text, float32 gap) {
	int16 width = 0;
	for (auto& t : text) {
		width += font.f_get字符宽度(t);
	}
	return width;
}


uint16 f_surface_get字符串宽度(const S_Font& font, std::u16string text, float32 gap) {
	uint16 width = 0;
	for (auto& t : text) {
		//if (t == '\t') width += font.m_字号 * 2 + gap;
		//else 
		width += uint16(font.f_get字符宽度(t) + gap);
	}
	return width;
}

uint16 f_surface_get字符串宽度(const S_Font& font, wchar_t text, float32 gap) {
	float32 w = font.f_get字符宽度(text);
	return uint16(w + gap);
}

uint32 f_mesh_gen网格元素绘制属性(S_Mesh* mesh, uint32 num) {
	f_bm_resize(mesh->m_网格元素变换属性, num);
	return mesh->m_网格元素变换属性.m_Mem.m_偏移;
}

uint32 f_mesh_resize间接绘制网格属性(S_Mesh* mesh, uint32 num) {
	f_bm_resize(mesh->m_网格元素变换属性, num);
	return mesh->m_网格元素变换属性.m_Mem.m_偏移;
}

void f_mesh_set网格元素绘制属性(S_Mesh* mesh, const S_MeshTranformProp& prop, uint32 offset) {
	mesh->m_网格元素变换属性.m_Buf->m_分配块内存锁.lock();
	f_buf_网格元素变换属性_at(mesh->m_网格元素变换属性, offset) = prop;
	mesh->m_网格元素变换属性.m_Buf->m_分配块内存锁.unlock();
}


void f_mesh_set绘制内存属性(S_Mesh* me, const S_Vert_MeshDrawProp& prop) {
	if (!me->m_绘制内存属性) {
		me->m_绘制内存属性 = (S_Vert_MeshDrawProp*)malloc(sizeof(S_Vert_MeshDrawProp));
	}
	(*(S_Vert_MeshDrawProp*)me->m_绘制内存属性) = prop;
	me->m_绘制属性字节大小 = sizeof(S_Vert_MeshDrawProp);
	me->m_绘制属性绑定阶段 = E_着色阶段::e_顶点着色;
}

void f_mesh_gen绘制内存属性_文本(S_Mesh* me, const S_ShaderConst_TextAttr& prop) {
	assert(!me->m_绘制内存属性);
	me->m_绘制内存属性 = (S_ShaderConst_TextAttr*)malloc(sizeof(S_ShaderConst_TextAttr));
	me->m_绘制属性字节大小 = sizeof(S_ShaderConst_TextAttr);
	(*(S_ShaderConst_TextAttr*)me->m_绘制内存属性) = prop;
	me->m_绘制属性绑定阶段 = E_着色阶段::e_几何着色;
}



struct S_GpuPick {
	Mat44f matrix;
	vec3 s;
	vec3 dir;
};





